package org.dragonnova.meetingserver.server.service;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Parcelable;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.iflytek.XFSynthesizer;
import com.ztspeech.AppAudio;
import com.ztspeech.ZTTranslate;

import org.dragonnova.meetingserver.R;
import org.dragonnova.meetingserver.core.net.socket.NetWorker;
import org.dragonnova.meetingserver.core.net.socket.UdpPacket;
import org.dragonnova.meetingserver.core.net.socket.UdpSocket;
import org.dragonnova.meetingserver.model.bean.VoiceInfo;
import org.dragonnova.meetingserver.server.application.TransBoxApplication;
import org.dragonnova.meetingserver.model.AObservable;
import org.dragonnova.meetingserver.model.IObserver;
import org.dragonnova.meetingserver.model.bean.DeviceInfo;
import org.dragonnova.meetingserver.model.bean.MeetingInfo;
import org.dragonnova.meetingserver.utils.Constants;
import org.dragonnova.meetingserver.utils.ContentResolverUtil;
import org.dragonnova.meetingserver.utils.LogUtil;
import org.dragonnova.meetingserver.utils.PromptUtil;
import org.dragonnova.meetingserver.utils.WifiAutoConnectUtil;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.dragonnova.meetingserver.core.SocketUtils;

/**
 * @author songxy
 *         Created at 2015/12/7 10:36
 *         Email: thinkdata@163.com
 *         用于管理WIFI网络入口、服务端通信、数据传输
 */
public class WIFIService extends Service {

    private final static String TAG = WIFIService.class.getName();

    public static final String MSG_UPDATED_ADAPTER = "org.dragonnova.wifihs.UPDATED_ADAPTER";
    public static final String MSG_VOICE_DATA_ADD = "org.dragonnova.wifihs.VOICE_DATA_ADD";

    /**
     * 当前的网络状态
     */
    public final static int NET_DISABLED_STATUS = 0;
    public final static int NET_WIFI_STATUS = 1;
    public final static int NET_ETHERNET_STATUS = 2;
    public final static int NET_MOBILE_STATUS = 3;

    /**
     * 用于ETHERNET组网状态标识：未开启，开启，未连接，连接中，已连接，连接断开
     */
    public final static int ETHERNET_DISABLED_STATUS = 20;
    public final static int ETHERNET_ENABLED_STATUS = 21;
    public final static int ETHERNET_CONNECTING_STATUS = 22;
    public final static int ETHERNET_CONNECTED_STATUS = 23;
    public final static int ETHERNET_DISCONNECTED_STATUS = 24;
    public final static int ETHERNET_INCORRECT_STATUS = 25;
    public final static int ETHERNET_CORRECT_STATUS = 26;

    /**
     * 用于WIFI组网状态标识：未开启，开启，未连接，连接中，已连接，连接断开
     */
    public final static int WIFI_DISABLED_STATUS = 10;
    public final static int WIFI_ENABLED_STATUS = 11;
    public final static int WIFI_CONNECTING_STATUS = 12;
    public final static int WIFI_CONNECTED_STATUS = 13;
    public final static int WIFI_DISCONNECTED_STATUS = 14;
    public final static int WIFI_INCORRECT_STATUS = 15;
    public final static int WIFI_CORRECT_STATUS = 16;
    /**
     * 网络的账号密码
     */
    public static final String KEY_WIFI_SSID = "WIFI_SSID";
    public static final String KEY_WIFI_PASSWD = "WIFI_PASSWD";
    /**
     * 应答机制 允许录音，不允许录音，服务端已经停止
     */
    public final static String KEY_VOICE_RESPONSE_PERMIT = "PERMIT";
    public final static String KEY_VOICE_RESPONSE_PREVENT = "PREVENT";
    public final static String KEY_VOICE_RESPONSE_FINISH = "FINISH";
    /**
     * 客户端列表维护
     */
    public final static LinkedHashSet<DeviceInfo> mDeviceInfoes = new LinkedHashSet<>();
    /**
     * action
     */
    private static final byte KEY_ACTION_GROUP_NO_JOIN = (byte) 0xBB;
    private static final byte KEY_ACTION_GROUP_ALLOW_JOIN = (byte) 0xAA;
    private static final byte KEY_ACTION_GROUP_JOINED = (byte) 0xDD;
    private static final int KEY_ACTION_GROUP_CONFIRM_1 = 0xEE;
    private static final int KEY_ACTION_GROUP_JOIN_REQUEST = 0xCC;
    private static final int KEY_ACTION_GROUP_CONFIRM_2 = 0xFF;
    private static final int KEY_ACTION_GROUP_CONNECTED_REQUEST = 0x01;
    private static final int KEY_ACTION_GROUP_CONNECTED_RESPONSE = 0x02;
    private static final int KEY_ACTION_GROUP_EXIT = 0x99;
    private static final int KEY_ACTION_GROUP_CHANGE_LANGUAGE = 0x31;
    private static final int KEY_ACTION_GROUP_CHANGE_LANGUAGE_COMPLETE = 0x32;
    private static final int KEY_ACTION_VOICE_REQUEST_START = 0x03;
    private static final int KEY_ACTION_VOICE_REQUEST_STOP = 0x04;
    private static final int KEY_ACTION_VOICE_REQUEST_PERSIST = 0x08;
    private static final int KEY_ACTION_VOICE_RESPONSE_PERMIT = 0x05;
    private static final int KEY_ACTION_VOICE_RESPONSE_PREVENT = 0x06;
    private static final int KEY_ACTION_VOICE_RESPONSE_FINISH = 0x07;
    private static final int KEY_ACTION_VOICE_RESPONSE_PERSIST = 0x09;
    private static final int KEY_ACTION_TRANSFER_VOICE_DATA = 0x10;
    private static final int KEY_ACTION_CREATE_MEETING = 0x19;
    private static final int KEY_ACTION_CREATE_MEETING_RESPONSE = 0x18;
    /**
     * 多播地址
     */
    private final static String MULTICAST_NETWORK_IP = "239.255.255.250";
    /**
     * 多播端口
     */
    private final static int MULTICAST_NETWORK_PORT = 25221;
    /**
     * 队列上限
     */
    private final static int VOICE_MAX_QUEUE_SIZE = 200;
    /**
     * 翻译请求次数
     */
    private final static int MAX_TASK_COUNT = 3;
    /**
     * UDP通信端口
     */
    private final static int SERVER_SOCKET_PORT = 30002;
    /**
     * UDP通信端口
     */
    private final static int SERVER_SOCKET_PORT_BEAT = 30001;
    /**
     * UDP通信端口
     */
    private final static int SERVER_SOCKET_PORT_VOICE_REQUEST = 30000;
    /**
     * 语音翻译，队列提交消费的批量次数
     */
    private static final int VOICE_DATA_QUEUES_TRANSFER_NUM = 3;
    /**
     * wifi网络当前状态
     */
    public static boolean isWifiEnabled = false;
    public static boolean isWifiApEnabled = false;
    /**
     * UDP服务端IP
     */
    public static String UDP_SERVER_IP;
    /**
     * 全局序号
     */
    private static AtomicInteger currentNum = new AtomicInteger(0);
    /**
     * 保存语音的队列，用于服务端的翻译
     */
    private LinkedBlockingQueue<VoiceInfo> voiceInfoTransQueue = new LinkedBlockingQueue<>(VOICE_MAX_QUEUE_SIZE);
    /**
     * 保存语音的队列，用于传输给其他连接的客户端
     */
    private LinkedBlockingQueue<VoiceInfo> voiceInfoBroadcastQueue = new LinkedBlockingQueue<>(VOICE_MAX_QUEUE_SIZE);
    /**
     * 用于网络状态的管理
     */
    private LinkedBlockingQueue<Integer> netObserverQueue = new LinkedBlockingQueue<>(VOICE_MAX_QUEUE_SIZE);
    /**
     * 用于注册观察者
     */
    private WIFIConnectionFactory factory = WIFIConnectionFactory.getInstance();
    /**
     * 组网数据域格式
     */
    private String[] mNetGroupDataFields;
    /**
     * 翻译任务次数
     */
    private AtomicInteger task_count = new AtomicInteger(0);
    /**
     * 用于UDP多播组网
     */
    private UdpSocket mMulticastSocket;

    /**
     * 服务起始时间
     */
    private long startTime;
    /**
     * 服务执行结束时间
     */
    private long endTime;
    /**
     * 本地网络状态
     */
    private int mCurrentNetStatus = NET_DISABLED_STATUS;
    /**
     * 本地WIFI动网络状态
     */
    private int mCurrentWifiStatus = WIFI_DISABLED_STATUS;
    /**
     * 本地WIFI动网络状态
     */
    private int mCurrentEthernetStatus = ETHERNET_DISABLED_STATUS;
    /**
     * 用于管理WIFI网络入口
     */
    private MainThread mainWorker;
    /**
     * 监听网络
     */
    private NetStatusObserverThread wifiObserver;
    /**
     * 组网接收线程
     */
    private MulticastRecThread multicastRecWorker;
    /**
     * UDP接收线程
     */
    private UdpWorker udpWorker;
    /**
     * UDP语音接收和发送线程
     */
    public BeatWorker beatWorker;
    /**
     * UDP语音接收和发送线程
     */
    public VoiceResWorker voiceResWorker;
    /**
     * ping网络的线程
     */
    public NetPingThread netPingWorker;
    /**
     * 多播锁
     */
    private WifiManager.MulticastLock multicastLock;
    //wifi、网络管理器
    private WifiManager mWifiManager;
    private ConnectivityManager mConnectivityManager;
    //binder
    private ServiceBinder serviceBinder;
    //翻译线程池
    private ExecutorService producerExecutorService;
    //语音包越位
    private int offset = 1;
    private VoiceProducer mProducer;
    private VoiceConsumer mConsumer;
    //网络状态广播接收
    private final NetGroupReceiver mNetReceiver = new NetGroupReceiver();
    //关于翻译的语音类
    private XFSynthesizer xfSynthesizer;//合成类
    private AppAudio mAppAudio;//录音和播放,包括录音开始、录音停止、播音开始、播音结束等

    /**
     * _(:3 」∠)_固定ip，测试
     */
    private static String UNIQUE_SSID = "G105-9";
    private static String UNIQUE_PASSWORD = "11111111";

    private MeetingInfo mMeetingInfo = new MeetingInfo();

    /**
     * 处理事件的handler
     */
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        Intent intent;

        public void handleMessage(Message msg) {
            switch (msg.what) {
                case AppAudio.TRANSLATE_ERROR:
                    Toast.makeText(WIFIService.this, "翻译错误", Toast.LENGTH_SHORT).show();
                    break;
                case AppAudio.TRANSLATED:
                    if (msg.arg1 == -1)
                        Toast.makeText(WIFIService.this, "录音时间请小于60s", Toast.LENGTH_SHORT).show();
                    else if (msg.arg1 == 1 && msg.arg2 == 1) {
                        VoiceInfo voiceInfo = (VoiceInfo) msg.obj;
                        voiceInfo.setFlag(1);
                        voiceInfo.setOrgCostTime(1);
                        String userId = TransBoxApplication.getInstance().getCurrentUserName();
                        if (TextUtils.isEmpty(userId)) {
                            userId = "null";
                        }
                        voiceInfo.setUserId(userId);
                        //在数据库中保存聊天记录
                        ContentResolverUtil resolverUtil = new ContentResolverUtil(WIFIService.this);
                        int id = resolverUtil.insertChatHistory(voiceInfo);
                        //刷新页面
                        intent = new Intent();
                        intent.setAction(Constants.TRANS_BORADCAST_ACTION);
                        intent.putExtra(Constants.BORADCAST_INTENT_OPTION, TranslationService.EXTRA_TRANSLATED);
                        intent.putExtra("voiceInfo", voiceInfo);
                        sendBroadcast(intent);
                        if (voiceInfo.getType() == 'c') {
                            xfSynthesizer.start(voiceInfo.getTranContent(), true);
                        } else {
                            xfSynthesizer.start(voiceInfo.getTranContent(), false);
                        }
                    }
                    break;
            }
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        //注册广播
        registerReceiver(mNetReceiver, getFilter());
        //初始化参数
        initParam();
        joinWifi();
        // TODO: 2016/1/6 wifi网络活动状态之下，启动组网线程
        wifiObserver = new NetStatusObserverThread();
        wifiObserver.start();
        //启动网络线程，组网、服务SOCKET初始化
        mainWorker = new MainThread();
        mainWorker.start();

    }

    /**
     * 初始化变量
     */
    private void initParam() {
        //起始时间
        startTime = System.currentTimeMillis();
        // <string-array name="net_group_data_field"><item>DEVICEID</item><item>WIFIADDR</item><item>WIFIPORT</item><item>BTADDR</item><item>BTNAME</item><item>TIMESTAMP</item><item>L</item></string-array>
        mNetGroupDataFields = getResources().getStringArray(R.array.net_group_data_field);
        //初始化WIFI相管理器
        mWifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
        //初始化网络管理
        mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        //启动线程池 8
        int poolSize = Runtime.getRuntime().availableProcessors() * 2;
        producerExecutorService = Executors.newFixedThreadPool(poolSize);
        //注册UDP回调 //监听Udp SOCKET
        factory.getObservable().addObserver(new WIFIObserver());
        //翻译对象
        xfSynthesizer = new XFSynthesizer(mHandler, WIFIService.this);

    }

    /**
     * 添加WIFI,网络活动状态下才能建立组网和UDP线程
     * 固定ip，自动组网
     */
    private void joinWifi() {
        //拿到网络状态，进行判断
        //[type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: "G105-2", roaming: false, failover: false, isAvailable: true, isConnectedToProvisioningNetwork: false]
        NetworkInfo networkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        //SSID: G105-2, BSSID: 30:fc:68:69:a1:04, MAC: cc:a2:23:36:10:a8, Supplicant state: COMPLETED, RSSI: -24, Link speed: 72Mbps, Frequency: 2462MHz, Net ID: 8, Metered hint: false, score: 100
        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
        //wifi是否未连接，数据服务要等到连接以后才能进行
        if ((networkInfo.getState() == NetworkInfo.State.CONNECTED) && wifiInfo.getSSID() != null && (wifiInfo.getSSID().equalsIgnoreCase("\"" + UNIQUE_SSID + "\"") || wifiInfo.getSSID().equalsIgnoreCase(UNIQUE_SSID))) {
            //192.168.1.100
            UDP_SERVER_IP = SocketUtils.convertIntIpAddress(getWifiInfo().getIpAddress());
        } else {
            doWifiRefresh(UNIQUE_SSID, UNIQUE_PASSWORD, "WAP");
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return Service.START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        multicastUnLock();
        try {
            unregisterReceiver(mNetReceiver);
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "onDestroy Error: " + e.getMessage());
        }
        stopAllThreadAndSocket();
        if (mainWorker != null) {
            mainWorker.close();
            mainWorker.setFlag(false);
            mainWorker.interrupt();
        }
        if (wifiObserver != null) {
            wifiObserver.setFlag(false);
            wifiObserver.interrupt();
        }

        shutDownThreadPool();
        endTime = System.currentTimeMillis();
    }

    /**
     * 销毁除了主线程和网络监听线程外的其他线程
     */
    private void stopAllThreadAndSocket() {
        if (multicastRecWorker != null) {
            multicastRecWorker.setFlag(false);
            multicastRecWorker.close();
            multicastRecWorker = null;
        }
        if (udpWorker != null) {
            udpWorker.setFlag(false);
            udpWorker.close();
            udpWorker = null;
        }
        if (voiceResWorker != null) {
            voiceResWorker.setFlag(false);
            voiceResWorker.close();
            voiceResWorker = null;
        }

        if (beatWorker != null) {
            beatWorker.setFlag(false);
            beatWorker.close();
            beatWorker = null;
        }

        if (mProducer != null) {
            mProducer.interrupt();
            mProducer = null;
        }
        if (mConsumer != null) {
            mConsumer.setFlag(false);
            mConsumer.interrupt();
            mConsumer = null;
        }
        if (netPingWorker != null) {
            netPingWorker.setFlag(false);
            netPingWorker = null;
        }
    }

    public void startAllThreadAndSocket() {
        //监听组网情况的线程
        Log.e(TAG, "BeatWorker Thread Start. ");
        DatagramSocket beatSocket = null;
        try {
            beatSocket = new DatagramSocket(new InetSocketAddress(
                    UDP_SERVER_IP, SERVER_SOCKET_PORT_BEAT));
            beatSocket.setSoTimeout(0);
            beatSocket.setReuseAddress(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
        UdpSocket beatSocket1 = new UdpSocket(beatSocket);
        beatWorker = new BeatWorker(beatSocket1);
        beatWorker.start();

        //应答机制的线程
        DatagramSocket voiceResSocket = null;
        try {
            voiceResSocket = new DatagramSocket(new InetSocketAddress(
                    UDP_SERVER_IP, SERVER_SOCKET_PORT_VOICE_REQUEST));
            voiceResSocket.setReuseAddress(true);
            voiceResSocket.setSoTimeout(1500);
        } catch (IOException e) {
            e.printStackTrace();
        }
        UdpSocket voiceReqSocket1 = new UdpSocket(voiceResSocket);
        voiceResWorker = new VoiceResWorker(voiceReqSocket1);
        voiceResWorker.start();

        //启动UDP语音包接收线程
        DatagramSocket udpSocket = null;
        try {
            udpSocket = new DatagramSocket(new InetSocketAddress(
                    UDP_SERVER_IP, SERVER_SOCKET_PORT));
            udpSocket.setReuseAddress(true);
            udpSocket.setSoTimeout(0);
        } catch (SocketException e) {
            e.printStackTrace();
        }
        if (udpSocket != null) {
            UdpSocket udpSocket1 = new UdpSocket(udpSocket);
            //客户端组播包 由ID和IP组成
            udpWorker = new UdpWorker(udpSocket1);
            udpWorker.start();
        }
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.i(TAG, "WIFIService unBind");
        serviceBinder = null;
        return false;
    }

    public IBinder onBind(Intent intent) {
        Log.i(TAG, "WIFIService onBind");
        serviceBinder = new ServiceBinder();
        return serviceBinder;
    }

    /**
     * 更新状态，通过主线程
     */
    public void refreshClientDevice(DeviceInfo deviceInfo, ActionType type) {
        Iterator<DeviceInfo> deviceInfoIterator;
        synchronized (mDeviceInfoes) {
            for (deviceInfoIterator = mDeviceInfoes.iterator(); deviceInfoIterator.hasNext(); ) {
                DeviceInfo temp = deviceInfoIterator.next();
                if (temp.equals(deviceInfo)) {
                    if (type.equals(ActionType.Update))
                        deviceInfoIterator.remove();
                }
            }
            mDeviceInfoes.add(deviceInfo);
        }
    }

    public boolean checkClientDevice(DeviceInfo info) {
        return mDeviceInfoes.contains(info);
    }

    /**
     * 查找设备信息
     */
    public DeviceInfo findDeviceInfoes(String btMacAddr, String clientId) {
        Iterator<DeviceInfo> deviceInfoIterator;
        for (deviceInfoIterator = mDeviceInfoes.iterator(); deviceInfoIterator.hasNext(); ) {
            DeviceInfo temp = deviceInfoIterator.next();
            if (temp.getHostId().equals(clientId)) {
                return temp;
            }
        }
        return null;
    }

    /**
     * 刷新网络
     */
    private void doWifiRefresh(final String ssid, final String passwd, final String wifiKey) {
        LogUtil.eee("dowifirefresh");
        new WifiAutoConnectUtil(mWifiManager).connect(ssid, passwd, WifiAutoConnectUtil.WifiCipherType.WIFICIPHER_WPA);
    }


    /**
     * 发送数据至客户端
     */
    public synchronized void sendPacketData(char language, SocketAddress addr, byte[] data) throws IOException {
        sendPacketData(language, addr, data, 0, data.length);
    }

    /**
     * 发送语音包向指定的地址
     */
    public synchronized void sendPacketData(char language, SocketAddress addr, byte[] data, int offset, int length)
            throws IOException {
        //根据客户端列表返回信息
        Iterator<DeviceInfo> deviceInfoIterator = null;
        for (deviceInfoIterator = mDeviceInfoes.iterator(); deviceInfoIterator.hasNext(); ) {
            DeviceInfo temp = deviceInfoIterator.next();
            if (temp.getWifiAddr() != null) {
                SocketAddress addr1 = new InetSocketAddress(temp.getWifiAddr(), temp.getPort());
                udpWorker.sendPacketData(data, new byte[]{KEY_ACTION_TRANSFER_VOICE_DATA}, addr1);
            }
        }
    }

    public boolean isMulticastSocketExisted() {
        return mMulticastSocket != null;
    }

    private IntentFilter getFilter() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
        filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        return filter;
    }

    private WifiInfo getWifiInfo() {
        return mWifiManager.getConnectionInfo();
    }

    /**
     * 加锁
     */
    private synchronized void multicastLock() {
        multicastLock = mWifiManager.createMulticastLock("GROUP LOCK");
        multicastLock.acquire();
    }

    /**
     * 解锁
     */
    private synchronized void multicastUnLock() {
        if (multicastLock != null)
            multicastLock.release();
    }

    /**
     * 关闭线程池
     */
    public void shutDownThreadPool() {
        if (producerExecutorService != null) {
            producerExecutorService.shutdown();
            try {
                while (!producerExecutorService.isTerminated())
                    producerExecutorService.awaitTermination(5000, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        producerExecutorService = null;
    }

    public enum ActionType {
        Update, Delete, Add
    }

    public class ServiceBinder extends Binder {
        public WIFIService getService() {
            return WIFIService.this;
        }
    }

    /**
     * 主线程，初始化WIFI连接，组播，服务端SOCKET
     */
    private class MainThread extends Thread {
        private InetAddress multiInetAddr;
        private boolean waitFlag = true;
        MulticastSocket socket = null;

        @Override
        public void run() {
            while (waitFlag) {
                try {
                    synchronized (this) {
                        wait();
                    }
                    while (!isMulticastSocketExisted()) {
                        try {
                            //加锁
                            multicastLock();
                            //启动多播套接字
                            socket = new MulticastSocket(MULTICAST_NETWORK_PORT);
                            multiInetAddr = InetAddress.getByName(MULTICAST_NETWORK_IP);
                            socket.joinGroup(multiInetAddr);
                            socket.setReuseAddress(true);
                            //设置本MulticastSocket发送的数据报被回送到自身
                            socket.setLoopbackMode(true);
                            //该ttl参数设置数据报最多可以跨过多少个网络，当ttl为0时，指定数据报应停留在本地主机；当ttl的值为1时，指定数据报发送到本地局域网；当ttl的值为32时，意味着只能发送到本站点的网络上；当ttl为64时，意味着数据报应保留在本地区；当ttl的值为128时，意味着数据报应保留在本大洲；当ttl为255时，意味着数据报可发送到所有地方；默认情况下，该ttl的值为1。
                            socket.setTimeToLive(1);
                            //封装
                            mMulticastSocket = new UdpSocket(socket);
                            Log.e(TAG, "MulticastSocket Start Join Group ");
                        } catch (IOException e) {
                            Log.e(TAG, "MulticastSocket IO ERROR: " + e.getMessage());
                            if (socket != null) {
                                try {
                                    socket.leaveGroup(multiInetAddr);
                                } catch (IOException e1) {
                                    e1.printStackTrace();
                                } finally {
                                    socket.close();
                                }
                            }
                            multicastUnLock();
                        }
                        if (isMulticastSocketExisted()) {
                            try {
                                //启动组网接收线程
                                multicastRecWorker = new MulticastRecThread(mMulticastSocket);
                                multicastRecWorker.start();
                                //启动ping线程
                                netPingWorker = new NetPingThread();
                                netPingWorker.start();
                                //发送数据到其他客户端的线程
                                mConsumer = new VoiceConsumer();
                                mConsumer.start();
                                //处理接收的udp包的线程
                                mProducer = new VoiceProducer();
                                mProducer.start();
                            } catch (Throwable e) {
                                Log.e(TAG, "Main Thread Error", e);
                            }
                        }
                        SystemClock.sleep(1000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    return;
                }
            }
        }

        public void close() {
            if (this.socket != null) {
                try {
                    socket.leaveGroup(multiInetAddr);
                    multicastUnLock();
                } catch (IOException e1) {
                    e1.printStackTrace();
                } finally {
                    socket.close();
                }
            }
        }

        public void setFlag(boolean flag) {
            this.waitFlag = flag;
        }
    }

    /**
     * 监听本机的网络变化情况
     */
    private class NetStatusObserverThread extends Thread {
        private boolean waitFlag = true;
        private int preMsg = -1;

        @Override
        public void run() {
            // 联网且是WIFI网络状态下
            while (waitFlag) {
                try {
                    int msg = netObserverQueue.take();
                    if (preMsg != msg) {
                        if (msg == 1) {
                            synchronized (mainWorker) {
                                mainWorker.notify();
                                startAllThreadAndSocket();
                            }
                        } else if (msg == 2) {
                            SystemClock.sleep(1000);
                            stopAllThreadAndSocket();
                            joinWifi();
                        } else if (msg == 0) {
                            SystemClock.sleep(1000);
                            stopAllThreadAndSocket();
                            joinWifi();
                        }
                    }
                    preMsg = msg;
                } catch (InterruptedException e) {
                    Log.e(TAG, "NetStatusObserverThread Interrupted " + e.getMessage());
                    return;
                }
            }
        }

        public void setFlag(boolean flag) {
            this.waitFlag = flag;
        }
    }

    private class NetPingThread extends Thread {
        private boolean waitFlag = true;
        private int disconnectedCount = 0;
        private int connectedCount = 0;

        @Override
        public void run() {
            // 联网且是WIFI网络状态下
            while (waitFlag) {
                Runtime run = Runtime.getRuntime();
                Process proc = null;
                try {
                    String str = "ping -c 1 -i 0.2 -W 1 " + "202.108.22.5";
                    System.out.println(str);
                    proc = run.exec(str);
                    int result = proc.waitFor();
                    if (result == 0) {
                        LogUtil.eee("Ping successfully");
                        if (connectedCount == 0)
                            PromptUtil.poolPlay(WIFIService.this, R.raw.internet_connected);
                        connectedCount++;
                        disconnectedCount = 0;
                    } else {
                        LogUtil.eee("Ping fail");
                        if (disconnectedCount == 5) {
                            PromptUtil.poolPlay(WIFIService.this, R.raw.internet_disconnected);
                            connectedCount = 0;
                        }
                        disconnectedCount++;
                    }
                } catch (IOException | InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    if (proc != null) proc.destroy();
                }
                SystemClock.sleep(5000);
            }
        }

        public void setFlag(boolean flag) {
            this.waitFlag = flag;
        }
    }

    /**
     * 组网接收线程
     */
    private class MulticastRecThread extends NetWorker {

        public MulticastRecThread(UdpSocket udpSocket) {
            super(udpSocket);
        }

        @Override
        public void work() {
            while (waitFlag) {
                try {
                    //客户端组播包 由ID和IP组成
                    UdpPacket packet = mMulticastSocket.receiveMsgFromNetwork(UdpSocket.PACKET_BUFFER_SIZE);
                    DatagramPacket inPacket = packet.getPacket();
                    if (inPacket != null && inPacket.getLength() > 0) {
                        Log.i(TAG, " receive Data from Remote: "
                                + inPacket.getAddress().getHostAddress());
                        doHandlerInPacket(packet);
                    } else
                        Log.i(TAG, " receive Data Is Null");
                } catch (Exception e) {
                    Log.e(TAG, " Error: " + e.getMessage());
                }
            }

        }

        private void doHandlerInPacket(UdpPacket packet) {
            int type = SocketUtils.byte2Int(packet.getMessage().getAction());
            DatagramPacket inPacket = packet.getPacket();
            DeviceInfo deviceInfo;
            switch (type) {
                case KEY_ACTION_GROUP_JOIN_REQUEST:
                    deviceInfo = DeviceInfo.parse(new String(packet.getMessage().getPacketData()));
                    boolean exist = checkClientDevice(deviceInfo);
                    //存在
                    try {
                        if (exist) {
                            sendPacketData(new byte[0], new byte[]{KEY_ACTION_GROUP_ALLOW_JOIN}, inPacket.getSocketAddress());
                        } else {
                            sendPacketData(new byte[0], new byte[]{KEY_ACTION_GROUP_NO_JOIN}, inPacket.getSocketAddress());
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                case KEY_ACTION_GROUP_CONFIRM_1:
                    try {
                        sendPacketData(new byte[0], new byte[]{KEY_ACTION_GROUP_ALLOW_JOIN}, inPacket.getSocketAddress());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                case KEY_ACTION_GROUP_CONFIRM_2:
                    deviceInfo = DeviceInfo.parse(new String(packet.getMessage().getPacketData()));
                    if (deviceInfo == null) break;
                    //加入
                    deviceInfo.setWifiStatus(DeviceInfo.Status.Connected);
                    refreshClientDevice(deviceInfo, ActionType.Update);
                    //存在
                    try {
                        sendPacketData(new byte[0], new byte[]{KEY_ACTION_GROUP_JOINED}, inPacket.getSocketAddress());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    PromptUtil.poolPlay(WIFIService.this, R.raw.client_grouped);
                    break;
                case KEY_ACTION_GROUP_EXIT:
                    deviceInfo = DeviceInfo.parse(new String(packet.getMessage().getPacketData()));
                    if (deviceInfo == null) break;
                    deviceInfo = findDeviceInfoes(deviceInfo.getBtMacAddr(), deviceInfo.getHostId());
                    if (deviceInfo == null) break;
                    deviceInfo.setWifiStatus(DeviceInfo.Status.DisConnected);
                    refreshClientDevice(deviceInfo, ActionType.Update);
                    break;
                case KEY_ACTION_GROUP_CHANGE_LANGUAGE:
                    deviceInfo = DeviceInfo.parse(new String(packet.getMessage().getPacketData()));
                    if (deviceInfo == null) break;
                    refreshClientDevice(deviceInfo, ActionType.Update);
                    //通知客户端
                    try {
                        sendPacketData(new byte[0], new byte[]{KEY_ACTION_GROUP_CHANGE_LANGUAGE_COMPLETE}, inPacket.getSocketAddress());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    Log.i(TAG, " UnKown action " + packet.getSocketAddress());
                    break;
            }
        }
    }

    /**
     * 用于维护客户端数据传输
     */
    public class UdpWorker extends NetWorker {

        public UdpWorker(UdpSocket udpSocket) {
            super(udpSocket);
        }

        @Override
        public void work() {
            while (waitFlag && isConnected()) {
                try {
                    UdpPacket packet = receiveMessage(UdpSocket.PACKET_BUFFER_SIZE);
                    if (packet.hasData()) {
                        Log.i(TAG, " receive Data from Remote: "
                                + ((InetSocketAddress) packet.getSocketAddress()).getHostName());
                        int action = SocketUtils.byte2Int(packet.getMessage().getAction());
                        switch (action) {
                            case KEY_ACTION_TRANSFER_VOICE_DATA:
                                factory.getObservable().handler(packet);
                                break;
                            case KEY_ACTION_CREATE_MEETING:
                                mMeetingInfo = MeetingInfo.parse(new String((packet.getMessage().getPacketData())));
                                LogUtil.eee(mMeetingInfo.toString());
                                //sendPacketData(mMeetingInfo.encode(), new byte[]{KEY_ACTION_CREATE_MEETING_RESPONSE}, packet.getSocketAddress());
                                sendPacketData(new byte[0], new byte[]{KEY_ACTION_GROUP_CONNECTED_RESPONSE}, packet.getSocketAddress());
                        }

                    } else
                        Log.i(TAG, " receive Data Is Null");
                } catch (Exception e) {
                    Log.e(TAG, "MulticastThread Error: " + e.getMessage());
                }

            }
            SystemClock.sleep(10000);
        }
    }

    /**
     * WIFI观察者
     */
    public class WIFIObserver implements IObserver {
        @Override
        public void doWhat(AObservable object, Object... args) {
            //播放语音
            UdpPacket packet = (UdpPacket) args[0];
            String msg = new String(packet.getMessage().getPacketData());
            VoiceInfo voiceInfo = VoiceInfo.parse(msg);
            LogUtil.eee(voiceInfo.toString());

            if (voiceInfo == null) {
                // TODO: 2015/12/25 未找到语音发过来的设备地址
                return;
            }
            // 加入队列
            voiceInfoTransQueue.add(voiceInfo);
        }
    }

    /**
     * 对传入的语音数据进行处理
     */
    private class VoiceProducer extends Thread {

        boolean mFlag = true;

        final ZTTranslate translate = new ZTTranslate(WIFIService.this.mHandler);

        private volatile VoiceInfo voiceInfo = null;

        private Runnable transfer_runnable = new Runnable() {

            @Override
            public void run() {
                //翻译请求
                doTransfer(voiceInfo);
            }
        };

        public VoiceProducer() {
            setName(VoiceProducer.class.getName());
        }

        /**
         * 云端识别、翻译、合成
         */
        synchronized void doTransfer(@NonNull VoiceInfo data) throws IndexOutOfBoundsException {
            task_count.set(0);
            if (data.getType() == 'c') {
                translate.setLanguage(ZTTranslate.LANGUAGE_MANDARIN);
            } else if (data.getType() == 'e') {
                translate.setLanguage(ZTTranslate.LANGUAGE_ENGLISH);
            }
            try {
                //请求翻译
                String transferStr = translate.start(data.getOrgContent());
                if (transferStr != null) transferStr = transferStr.trim();
                data.setTranContent(transferStr);
                //放入队列
                voiceInfoBroadcastQueue.add(voiceInfo);
                task_count.set(task_count.incrementAndGet());
            } catch (Exception e) {
                if (task_count.intValue() < MAX_TASK_COUNT) {
                    doTransfer(data);
                } else {
                    throw new IndexOutOfBoundsException("Transfer Commit Over " + MAX_TASK_COUNT + " Times");
                }
            }
        }

        @Override
        public void run() {
            try {
                while (mFlag || !Thread.interrupted()) {
                    voiceInfo = voiceInfoTransQueue.take();
                    producerExecutorService.execute(transfer_runnable);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 将语音处理结果返回客户端
     */
    private class VoiceConsumer extends Thread {

        boolean mFlag = true;

        @Override
        public void run() {
            try {
                while (mFlag || !Thread.interrupted()) {
                    //返回客户端
                    VoiceInfo voiceInfo = voiceInfoBroadcastQueue.take();
                    try {
                            /*VoiceInfo{id=0 orgData=null tranData=null orgContent='I saw you in.' tranContent='我看到你在。' inserttime=1460710583530 type=e orgPath='null' orgAddress=null orgCosttime=0 userId='null' flag=0}*/
                        //VoiceInfo voiceInfo = voiceInfoTransQueue.remove();
                        // TODO: 2016/1/8 返回客户端翻译的语
                        byte[] result = voiceInfo.encode();
                        if (result.length == 0) continue;
                        //MIPS 转换大端
                        Log.i(TAG, "接收到并转发数据--" + voiceInfo.toString() + "--");
                        WIFIService.this.sendPacketData(voiceInfo.getType(), voiceInfo.getOrgAddress(), result);
                        //通知Handler
                        mHandler.obtainMessage(AppAudio.TRANSLATED, 1, 1, voiceInfo).sendToTarget();
                        Log.d(TAG, "ExecutorService Transfer Data Id-" + voiceInfo.getId() + " Complete"
                                + "SendData Successful When " + System.currentTimeMillis());

                    } catch (NullPointerException e) {
                        Log.e(TAG, "VoiceInfo is Null " + e.getMessage());
                    } catch (NoSuchElementException | IOException e) {
                        Log.e(TAG, "", e);
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        /**
         * 结束此线程
         */
        public void setFlag(boolean flag) {
            this.mFlag = flag;
        }
    }

    /**
     * 用于检查网络状况
     */
    class BeatWorker extends NetWorker {

        public BeatWorker(UdpSocket udpSocket) {
            super(udpSocket);
        }

        @Override
        public void work() {
            while (waitFlag && isConnected()) {
                try {
                    UdpPacket inPacket = receiveMessage(UdpSocket.PACKET_BUFFER_SIZE);
                    if (inPacket.hasData()) {
                        Log.i(TAG, " receive Data from Remote: "
                                + inPacket.getSocketAddress());
                        int type = SocketUtils.byte2Int(inPacket.getMessage().getAction());
                        switch (type) {
                            case KEY_ACTION_GROUP_CONNECTED_REQUEST:
                                sendPacketData(new byte[0], new byte[]{KEY_ACTION_GROUP_CONNECTED_RESPONSE}, inPacket.getSocketAddress());
                                DeviceInfo deviceInfo = DeviceInfo.parse(new String(inPacket.getMessage().getPacketData()));
                                if (deviceInfo == null) {
                                    LogUtil.e("接收到的数据为空");
                                    break;
                                }
                                DeviceInfo deviceInfo1 = findDeviceInfoes(
                                        deviceInfo.getBtMacAddr(), deviceInfo.getHostId());
                                if (deviceInfo1 != null) {
                                    deviceInfo1.setDisconnectedCount(0);
                                }
                                Iterator<DeviceInfo> deviceInfoIterator;
                                for (deviceInfoIterator = mDeviceInfoes.iterator(); deviceInfoIterator.hasNext(); ) {
                                    DeviceInfo temp = deviceInfoIterator.next();
                                    if (temp.getWifiStatus() == DeviceInfo.Status.Connected) {
                                        temp.setDisconnectedCount(temp.getDisconnectedCount() + 1);
                                    }
                                    if (temp.getDisconnectedCount() > 10) {
                                        temp.setWifiStatus(DeviceInfo.Status.DisConnected);
                                    }
                                    LogUtil.e(temp.toString());
                                }
                                break;
                        }
                    } else {
                        Log.i(TAG, "no data received");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 用于维护客户端数据传输
     */
    class VoiceResWorker extends NetWorker {
        private String inputAddress = null;

        public VoiceResWorker(UdpSocket udpSocket) {
            super(udpSocket);
        }

        @Override
        public void work() {
            while (waitFlag && isConnected()) {
                try {
                    UdpPacket inPacket = receiveMessage(UdpSocket.PACKET_BUFFER_SIZE);
                    try {
                        if (inPacket.hasData()) {
                            Log.i(TAG, "VoiceResWorker ===========================================receive Data from Remote: "
                                    + inPacket.getSocketAddress());
                            try {
                                String tempAddress = inPacket.getSocketAddress().toString();
                                int type = SocketUtils.byte2Int(inPacket.getMessage().getAction());
                                switch (type) {
                                    case KEY_ACTION_VOICE_REQUEST_START:
                                        if (TextUtils.isEmpty(inputAddress)) {
                                            sendPacketData(new byte[0], inPacket.getSocketAddress(), 1);
                                            inputAddress = tempAddress;
                                            PromptUtil.poolPlay(WIFIService.this, R.raw.prompt_permit);
                                        } else {
                                            sendPacketData(new byte[0], inPacket.getSocketAddress(), 2);
                                        }
                                        break;
                                    case KEY_ACTION_VOICE_REQUEST_STOP:
                                        sendPacketData(new byte[0], inPacket.getSocketAddress(), 3);
                                        if (tempAddress.equals(inputAddress)) {
                                            inputAddress = null;
                                        }
                                        break;
                                    case KEY_ACTION_VOICE_REQUEST_PERSIST:
                                        if (TextUtils.equals(inputAddress, tempAddress)) {
                                            sendPacketData(new byte[0], inPacket.getSocketAddress(), 4);
                                        } else {
                                            sendPacketData(new byte[0], inPacket.getSocketAddress(), 2);
                                        }
                                        break;
                                }
                            } catch (NullPointerException e) {
                                e.printStackTrace();
                            }
                        } else {
                            LogUtil.i(TAG, "no data received");
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (SocketTimeoutException e) {
                    LogUtil.eee("no voice input request or input is stopped or input is disconnected");
                    inputAddress = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        public synchronized void sendPacketData(byte[] data, SocketAddress beatAddr, int action) throws IOException {
            if (isConnected()) {
                byte[] actionBytes = null;
                if (action == 1) {
                    actionBytes = new byte[]{KEY_ACTION_VOICE_RESPONSE_PERMIT};
                } else if (action == 2) {
                    actionBytes = new byte[]{KEY_ACTION_VOICE_RESPONSE_PREVENT};
                } else if (action == 3) {
                    actionBytes = new byte[]{KEY_ACTION_VOICE_RESPONSE_FINISH};
                } else if (action == 4) {
                    actionBytes = new byte[]{KEY_ACTION_VOICE_RESPONSE_PERSIST};
                }
                sendPacketData(data, actionBytes, beatAddr);
            } else {
                LogUtil.eee("UDP Socket Status is " + " , Current Net Status: " + mCurrentNetStatus);
            }
        }
    }


    /**
     * 网络的全局广播
     */
    private class NetGroupReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
            WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
            if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                //进入应用首先会检查网络状况
                if (networkInfo != null && networkInfo.isConnected()) {
                    ///网络连接
                    if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                        //wifi连接
                        LogUtil.eee("NET_TYPE_WIFI_CONNECTED");
                        mCurrentNetStatus = NET_WIFI_STATUS;
                    } else if (networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
                        //有线网络
                        LogUtil.eee("NET_TYPE_ETHERNET_CONNECTED");
                        mCurrentNetStatus = NET_ETHERNET_STATUS;
                        try {
                            String ethernetIp = null;
                            for (Enumeration<NetworkInterface> en = NetworkInterface
                                    .getNetworkInterfaces(); en.hasMoreElements(); ) {
                                NetworkInterface intf = en.nextElement();
                                for (Enumeration<InetAddress> enumIpAddr = intf
                                        .getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                                    InetAddress inetAddress = enumIpAddr.nextElement();
                                    if (!inetAddress.isLoopbackAddress()) {
                                        ethernetIp = inetAddress.getHostAddress();
                                        LogUtil.eee("ethernetIp = " + ethernetIp);
                                    }
                                }
                            }
                            if (ethernetIp != null && !ethernetIp.equals(UDP_SERVER_IP)) {
                                UDP_SERVER_IP = ethernetIp;
                            }
                            try {
                                netObserverQueue.put(1);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        } catch (SocketException ex) {
                            ex.printStackTrace();
                        }
                    } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                        //3g网络
                        LogUtil.eee("NET_TYPE_MOBILE_CONNECTED");
                        mCurrentNetStatus = NET_MOBILE_STATUS;
                    }
                } else if (networkInfo != null && networkInfo.isAvailable()) {
                    //有网络，但是没有连接
                    LogUtil.eee("NET_TYPE_AVAILABLE");
                    ///网络连接
                    if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                        //wifi连接
                        LogUtil.eee("NET_TYPE_WIFI_DISCONNECTED");
                        mCurrentNetStatus = NET_WIFI_STATUS;

                    } else if (networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
                        //有线网络
                        LogUtil.eee("NET_TYPE_ETHERNET_DISCONNECTED");
                        mCurrentNetStatus = NET_ETHERNET_STATUS;

                    } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                        //3g网络
                        LogUtil.eee("NET_TYPE_MOBILE_DISCONNECTED");
                        mCurrentNetStatus = NET_MOBILE_STATUS;
                    }
                } else {
                    //其他状态
                    LogUtil.eee("NET_TYPE_NOT_AVAILABLE");
                    //如果没有网络，那么默认打开wifi
                    mCurrentNetStatus = NET_WIFI_STATUS;
                    joinWifi();
                }
            } else if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED);
                switch (wifiState) {
                    case WifiManager.WIFI_STATE_DISABLED:
                        LogUtil.e("WifiState", "DISABLED");
                        mCurrentWifiStatus = WIFI_DISABLED_STATUS;
                        if (mCurrentNetStatus == NET_WIFI_STATUS) {
                            try {
                                netObserverQueue.put(0);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        break;
                    case WifiManager.WIFI_STATE_DISABLING:
                        break;
                    case WifiManager.WIFI_STATE_ENABLED:
                        LogUtil.e("WifiState", "ENABLED");
                        if (mCurrentNetStatus == NET_DISABLED_STATUS) {
                            mCurrentWifiStatus = WIFI_ENABLED_STATUS;
                            mCurrentNetStatus = NET_WIFI_STATUS;
                        }
                        break;
                    case WifiManager.WIFI_STATE_ENABLING:
                        break;
                    case WifiManager.WIFI_STATE_UNKNOWN:
                        break;
                }
            } else if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
                if (null != parcelableExtra) {
                    NetworkInfo info = (NetworkInfo) parcelableExtra;
                    switch (info.getState()) {
                        case CONNECTED:
                            // 网络已连接
                            LogUtil.e("WifiState", "CONNECTED");
                            mCurrentWifiStatus = WIFI_CONNECTED_STATUS;
                            if (wifiInfo.getSSID() != null && (wifiInfo.getSSID().equalsIgnoreCase("\"" + UNIQUE_SSID + "\"") || wifiInfo.getSSID().equalsIgnoreCase(UNIQUE_SSID))) {
                                LogUtil.e("WifiState", "CORRECT");
                                mCurrentWifiStatus = WIFI_CORRECT_STATUS;
                                String currentIp = SocketUtils.convertIntIpAddress(wifiInfo.getIpAddress());
                                if (currentIp != null && !currentIp.equals(UDP_SERVER_IP)) {
                                    UDP_SERVER_IP = currentIp;
                                }
                                try {
                                    netObserverQueue.put(1);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            } else {
                                //连接的不是制定的网络
                                LogUtil.e("WifiState", "INCORRECT");
                                mCurrentWifiStatus = WIFI_INCORRECT_STATUS;
                                try {
                                    netObserverQueue.put(2);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            break;
                        case CONNECTING:
                            LogUtil.e("WifiState", "CONNECTING");
                            break;
                        case DISCONNECTED:
                            LogUtil.e("WifiState", "DISCONNECTED");
                            mCurrentWifiStatus = WIFI_DISCONNECTED_STATUS;
                            if (mCurrentNetStatus == NET_WIFI_STATUS) {
                                try {
                                    netObserverQueue.put(0);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            break;
                        case DISCONNECTING:
                            LogUtil.e("WifiState", "DISCONNECTING");
                            break;
                        case SUSPENDED:
                            LogUtil.e("WifiState", "SUSPENDED");
                            break;
                        case UNKNOWN:
                            LogUtil.e("WifiState", "UNKNOWN");
                            break;
                        default:
                            break;
                    }
                }
            } else if (intent.getAction().equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
                Boolean state = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false);
                Log.d(TAG, "NetworkInfo connected Statue: " + state);
            } else if (intent.getAction().equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
                SupplicantState state = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
                Log.d(TAG, "NetworkInfo connected Statue: " + state);
            } else if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                List<ScanResult> results = mWifiManager.getScanResults();
                for (ScanResult result : results) {
                    Log.d(TAG, "SCAN_RESULTS_AVAILABLE_ACTION " + "BSSID: " + result.BSSID
                            + ", SSID: " + result.SSID);
                }
            }
        }
    }
}
